Clipboard Transfer
The clipboard commands Cut, Copy, and Paste constitute a common mechanism for transferring data within and across conventional documents, even documents of different data formats. For OpenDoc documents, these commands perform the same tasks, but with added capabilities.
As with data placed in a conventional clipboard, if your part editor stores multiple formats on the clipboard--including standard formats--the user has a greater chance of being able to incorporate (rather than embed) the data into more kinds of parts.
- The commands operate on embedded parts as well as intrinsic content. The data copied to or pasted from the clipboard can contain any number of parts, of any part kinds. The parts may be displayed in frames or represented as icons.
- The Paste and Paste As commands can either embed parts or incorporate data as intrinsic content.
- The Paste and Paste As commands can cause a portion of one part's intrinsic content to become, when copied and then pasted into another part, a separate, embedded part on its own.
- The Paste As command can create a persistent link to the source of the data being pasted.
- The Paste As command also allows the user to override decisions on incorporating versus embedding that would normally be made by OpenDoc.
Clipboard Concepts
This section discusses some basic clipboard operations common to both reading and writing, such as acquiring the clipboard focus and using the clipboard update ID. It also presents some special considerations related to updating the clipboard and cutting data from your part.
- Enabling the Cut and Paste menu items
- OpenDoc does not permit changes to your draft (and therefore your part's content) if the draft permissions are read-only. You should check your draft permissions (see "Drafts") before enabling the Cut, Paste, or Paste As items in the Edit menu or before allowing the user to perform a cut or paste operation using keyboard equivalents.
![]()
Acquiring and Relinquishing the Clipboard Focus
Your part can access the clipboard only when your part is in the foreground process; access from a background process is meaningless. Furthermore, to be thread-safe, you must always acquire the clipboard focus before writing or reading clipboard data. As long as you hold the clipboard focus, no other part should access or modify the data.Typically, your part needs to inspect the contents of the clipboard before deciding whether to enable Edit menu items, so your
AdjustMenus
method can include a call to the arbitrator'sRequestFocus
method to acquire the clipboard focus.After acquiring the clipboard focus, you can access the clipboard when responding to a menu command (or its keyboard equivalent) with your
HandleEvent
method by calling the session object'sGetClipboard
method. You should then unilaterally relinquish the clipboard focus in yourHandleEvent
method, after having handled the clipboard command. (YourHandleEvent
method is always called afterAdjustMenus
is called, even if the user does not choose a menu command.)These are the steps you take to acquire the clipboard focus and prepare to write to the clipboard or read from it:
You relinquish the clipboard focus unilaterally by calling the arbitrator's
- Acquire the clipboard focus, using the Arbitrator's
RequestFocus
method (as described in "Requesting Foci").- Gain access to the clipboard object, using the session object's
GetClipboard
method.- If you are writing to the clipboard, remove any existing data on the clipboard with the clipboard's
Clear
method. (Do not take this step if you are reading from the clipboard.)- Gain access to the clipboard's content storage unit, using the clipboard's
GetContentStorageUnit
method.
RelinquishFocus
method.Clipboard Update ID
Whenever you copy data to the clipboard, you should get and save the clipboard's current update ID, a number used to identify this particular instance of clipboard contents. You typically obtain the update ID in this situation by calling the clipboard'sActionDone
method. In other situations, you may need to inspect the clipboard's current update ID; you can do so by calling the clipboard'sGetUpdateID
method.If a link specification that you have written to the clipboard becomes invalid because of changes to your content that was copied to the clipboard, you must remove the link specification from the clipboard, as described under "Removing a Link Specification From the Clipboard" (next). You can examine the clipboard's current update ID at any time and compare it with your saved update ID; if they are identical, the clipboard has not changed.
Removing a Link Specification From the Clipboard
If your part copies some of its content to the clipboard and the user then modifies the equivalent content in your part (without copying anything else to the clipboard), the clipboard data no longer matches the source data in your part. The potential link represented by the link specification you wrote in the clipboard therefore no longer reflects the content at the source of the link. If your source content has changed to the extent that creating a link is no longer feasible, your part must remove the link specification.By saving the update ID of the clipboard whenever you copy data to it, you can check that ID against the current update ID of the clipboard whenever your source data changes to the extent that creating a link to the previous data is impossible. If the IDs match, the clipboard still contains the data that you placed in it, and you should remove the link specification.
You can follow these steps to remove a link specification:
- Acquire the clipboard focus as described in the section "Acquiring and Relinquishing the Clipboard Focus".
- Get the clipboard's update ID and compare it to your stored update ID. If they don't match, skip to step 5.
- Access the clipboard's content storage unit. (Unlike when writing to the clipboard, do not clear the clipboard data.)
- Focus the storage unit on the link-specification property (type
kODLinkSpec
) and remove that property, using the storage unit'sRemove
method. Be sure to focus on the entire property (by specifying a null value type), so that you remove the entire property and not just one value.- Relinquish the clipboard focus.
Undo for Clipboard
If your part supports cutting or pasting, it must also support undoing those operations. (Note that data transfer between parts is undoable only if both parts involved have undo support.) Undo support in general is described in the section "Undo".Whenever your part performs a cut, copy, or paste operation, it must call the clipboard's
ActionDone
method to notify the clipboard of the kind of cloning transaction that took place.ActionDone
returns a clipboard ID that identifies the current clipboard contents. Save that update ID.When your part cuts an object to the clipboard, it should remove the object from its content data structures. However, your part should not release the object, but instead save a reference to the object in an undo action. (For a cut embedded frame, you also set its in-limbo flag to true, as shown in Table 6-4UndoAction method is called, your part should
If the user subsequently chooses the Redo command and your part's
- reinstate the object in your part's content structures (and setting its in-limbo flag to false)
- notify the clipboard that the cut was undone, by calling the clipboard's
ActionUndone
method, passing it the update ID returned to you when you calledActionDone
after cutting the data to the clipboard
RedoAction
method is called, your part should
Calling
- once again remove the object from its content data structures (and reset its in-limbo flag to true)
- notify the clipboard that the cut was redone, by calling the clipboard's
ActionRedone
method, passing it the same update ID
ActionDone
,ActionUndone
, andActionRedone
notifies the clipboard whether it is involved in a cut, a copy, or the restoration of a cut or a copy; the clipboard's internal handling of its objects differs in each case.If and when your part's
DisposeActionState
method is called, you can at that point release (not remove from your draft) the object referenced in your undo action. (For an embedded frame, you either release or remove it, as shown in Table 6-4.)To undo a cut, copy, or paste operation requires the restoration of the previous state of the document involved, but it does not require the restoration of the previous state of the clipboard. Therefore, if you redo a paste operation that has been undone, you cannot assume that the clipboard once again contains the original data that had been pasted. You must implement the redo from your own data. For this reason, you should retain a copy of pasted data in a private cache.
Copying or Cutting to the Clipboard
You write data to the clipboard as a result of the user selecting the Cut command or the Copy command from the Edit menu (or their keyboard equivalents). These are the basic steps to take:
- Acquire the clipboard focus and access the clipboard's content storage unit, as described in the section "Acquiring and Relinquishing the Clipboard Focus".
- Write the data to the clipboard.
- If the selection consists of a combination of your part's intrinsic content plus zero or more embedded parts, you need to write your own intrinsic content to the clipboard, and you need to clone the embedded frames and parts as well (or you can write a promise). Follow the steps listed in the section "Writing Intrinsic Content".
- If the selection consists of a single frame of an embedded part with no surrounding intrinsic content, you need to clone the part and provide a frame for it. Follow the steps listed in the section "Writing a Single Embedded Part".
In either case, when you call the
BeginClone
method, specify eitherkODCloneCopy
orkODCloneCut
, depending on whether you are copying or cutting the data to the clipboard.
- When you have finished, call the clipboard's
ActionDone
method, specifying eitherkODCloneCopy
orkODCloneCut
. Save the clipboard's current update ID (see "Clipboard Update ID"), which is returned from ActionDone, in case you later have to undo the cut or copy, remove a link specification, or fulfill a promise you wrote.- If this operation was a cut rather than a copy, it must be undoable. Add a single action to the action history, as described in "Adding an Action to the Undo Action History", including setting the in-limbo flag of any cut frame to true.
- Delete the cut selection from your part's content.
- Relinquish the clipboard focus (see "Acquiring and Relinquishing the Clipboard Focus"
Pasting From the Clipboard
You read data from the clipboard as a result of the user selecting the Paste command or the Paste As command from the Edit menu. These are the basic steps to take:
- Acquire the clipboard focus and access the clipboard's content storage unit, as described in the section "Acquiring and Relinquishing the Clipboard Focus". (Do not clear the clipboard data, of course.)
- Read the data from the clipboard.
- If the data consists of intrinsic content plus zero or more embedded frames, and if the intrinsic content is of a part kind that you can incorporate into your part, you need to read the intrinsic content and possibly clone embedded parts, links, or other objects. Follow the steps listed in the section "Incorporating Intrinsic Content".
- If you need to embed the data as a single part with no surrounding intrinsic content, you need to clone the part and either extract its frame or create a frame for it. Follow the steps listed in the section "Embedding a Single Part". That section lists the conditions under which you must embed rather than incorporate clipboard data.
In either case, when you call the
BeginClone
method, specifykODClonePaste
.
- Pasting must be an undoable operation. Call the clipboard's
ActionDone
method, specifyingkODClonePaste
. Save the current clipboard update ID, returned byActionDone
, in a single undo action (see "Adding an Action to the Undo Action History". In this case, save the current value of the frame's in-limbo flag and then set the flag to false.Clipboard content is not transferred when a link is pasted. Thus, your part should not call the clipboard's
ActionDone
method.- Notify OpenDoc and your containing part that your part's content has changed; see "Making Content Changes Known".
- Relinquish the clipboard focus (see "Acquiring and Relinquishing the Clipboard Focus"
Main | Page One | What's New | Apple Computer, Inc. | Find It | Contact Us | Help